package jdklearning.concurrent.threadpool;


import java.util.HashSet;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * https://www.sohu.com/a/120029749_355142
 * https://www.iflym.com/index.php/code/201510080001.html
 * @author shenenlu 2021年06月17日 下午21:28:00
 */
public class MockThreadPool {


    private HashSet<Worker> workerSet = new HashSet<>();

    private BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(100);


    public void execute(Runnable runnable){
        if (addWorker(runnable)){
            return;
        }
        workQueue.offer(runnable);
    }

    private boolean addWorker(Runnable runnable) {
        Worker worker = new Worker(runnable);
        Thread thread = worker.thread;

        boolean workerAdded = false;
        workerSet.add(worker);
        workerAdded=true;

        boolean workerStarted = false;

        if( workerAdded ){
            thread.start();
            workerStarted = true;
        }

        return workerAdded;
    }

    private void runWorker(Worker worker) {
        Thread thread = Thread.currentThread();
        Runnable task = worker.runnable;
        while ( task != null || (task = getTask()) != null){
            task.run();
        }
    }

    private Runnable getTask() {
        return null;
    }


    private final class Worker implements Runnable{

        Runnable runnable;
        final Thread thread;

        /**
         * Creates with given first task and thread from ThreadFactory.
         * @param firstTask the first task (null if none)
         */
        Worker(Runnable firstTask) {
//            setState(-1); // inhibit interrupts until runWorker
            this.runnable = firstTask;
            this.thread = new Thread(this);
        }

        @Override
        public void run() {
            runWorker(this);
        }


    }


    public static void main(String[] args) {
        MockThreadPool mockThreadPool = new MockThreadPool();
        mockThreadPool.execute(()->{
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName());
        });
    }

}
